home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / faxd / Class2Params.c++ < prev    next >
C/C++ Source or Header  |  1994-08-01  |  11KB  |  392 lines

  1. /*    $Header: /usr/people/sam/fax/faxd/RCS/Class2Params.c++,v 1.11 1994/02/28 14:14:57 sam Rel $ */
  2. /*
  3.  * Copyright (c) 1990, 1991, 1992, 1993, 1994 Sam Leffler
  4.  * Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11.  * publicity relating to the software without the specific, prior written
  12.  * permission of Sam Leffler and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. #include "Class2Params.h"
  26. #include "t.30.h"
  27.  
  28. /*
  29.  * Tables for printing some Class 2 capabilities.
  30.  */
  31. const char* Class2Params::vresNames[2] = {
  32.     "3.85 line/mm",
  33.     "7.7 line/mm",
  34. };
  35. const char* Class2Params::bitRateNames[8] = {
  36.     "2400 bit/s",        // BR_2400
  37.     "4800 bit/s",        // BR_4800
  38.     "7200 bit/s",        // BR_7200
  39.     "9600 bit/s",        // BR_9600
  40.     "12000 bit/s",        // BR_12000
  41.     "14400 bit/s",        // BR_14400
  42.     "0 bit/s",            // 6 ???
  43.     "0 bit/s",            // 7 ???
  44. };
  45. const char* Class2Params::dataFormatNames[4] = {
  46.     "1-D MR",            // DF_1DMR
  47.     "2-D MR",            // DF_2DMR
  48.     "2-D Uncompressed Mode",    // DF_2DUNCOMP
  49.     "2-D MMR"            // DF_2DMMR
  50. };
  51. const char* Class2Params::pageWidthNames[8] = {
  52.     "page width 1728 pixels in 215 mm",
  53.     "page width 2048 pixels in 255 mm",
  54.     "page width 2432 pixels in 303 mm",
  55.     "page width 1216 pixels in 151 mm",
  56.     "page width 864 pixels in 107 mm",
  57.     "undefined page width (wd=5)",
  58.     "undefined page width (wd=6)",
  59.     "undefined page width (wd=7)",
  60. };
  61. const char* Class2Params::pageLengthNames[4] = {
  62.     "A4 page length (297 mm)",
  63.     "B4 page length (364 mm)",
  64.     "unlimited page length ",
  65.     "invalid page length (ln=3)",
  66. };
  67. const char* Class2Params::scanlineTimeNames[8] = {
  68.     "0 ms/scanline",
  69.     "5 ms/scanline",
  70.     "10 ms, 5 ms/scanline",
  71.     "10 ms/scanline",
  72.     "20 ms, 10 ms/scanline",
  73.     "20 ms/scanline",
  74.     "40 ms, 20 ms/scanline",
  75.     "40 ms/scanline",
  76. };
  77.  
  78. Class2Params::Class2Params()
  79. {
  80. }
  81.  
  82. int
  83. Class2Params::operator==(const Class2Params& other) const
  84. {
  85.     return vr == other.vr
  86.     && br == other.br
  87.     && wd == other.wd
  88.     && ln == other.ln
  89.     && df == other.df
  90.     && ec == other.ec
  91.     && bf == other.bf
  92.     && st == other.st;
  93. }
  94.  
  95. int
  96. Class2Params::operator!=(const Class2Params& other) const
  97. {
  98.     return !(*this == other);
  99. }
  100.  
  101. static char*
  102. addParam(char* cp, u_int v)
  103. {
  104.     if (v != (u_int)-1) {
  105.     sprintf(cp, ",%u", v);
  106.     while (*cp != '\0') cp++;
  107.     } else {
  108.     *cp++ = ',';
  109.     *cp = '\0';
  110.     }
  111.     return (cp);
  112. }
  113.  
  114. fxStr
  115. Class2Params::cmd() const
  116. {
  117.     char buf[1024];
  118.     char* cp = buf;
  119.  
  120.     if (vr != -1) {
  121.     sprintf(cp, "%u", vr);
  122.     while (*cp != '\0') cp++;
  123.     }
  124.     cp = addParam(cp, br);
  125.     cp = addParam(cp, wd);
  126.     cp = addParam(cp, ln);
  127.     cp = addParam(cp, df);
  128.     cp = addParam(cp, ec);
  129.     cp = addParam(cp, bf);
  130.     cp = addParam(cp, st);
  131.     return fxStr(buf);
  132. }
  133.  
  134. fxBool
  135. Class2Params::is2D() const
  136. {
  137.     return (DF_2DMR <= df && df <= DF_2DMRUNCOMP);
  138. }
  139.  
  140. /*
  141.  * Tables to convert from Class 2
  142.  * subparameter codes to a T.30 DIS.
  143.  */
  144. u_int Class2Params::vrDISTab[2] = {
  145.     0,                // VR_NORMAL
  146.     DIS_7MMVRES            // VR_FINE
  147. };
  148. u_int Class2Params::dfDISTab[4] = {
  149.     0,                // 1-D MR
  150.     DIS_2DENCODE,        // + 2-D MR
  151.     DIS_2DENCODE,        // + Uncompressed data
  152.     DIS_2DENCODE,        // + 2-D MMR
  153. };
  154. u_int Class2Params::brDISTab[8] = {
  155.     DISSIGRATE_V27FB<<10,        // BR_2400
  156.     DISSIGRATE_V27<<10,            // BR_4800
  157.     (DISSIGRATE_V27|DISSIGRATE_V29)<<10,// BR_7200
  158.     (DISSIGRATE_V27|DISSIGRATE_V29)<<10,// BR_9600
  159.     0xD,                // BR_12000 (v.27,v.29,v.17,v.33)
  160.     0xD,                // BR_14400 (v.27,v.29,v.17,v.33)
  161.     (DISSIGRATE_V27|DISSIGRATE_V29)<<10,// 6 ?
  162.     (DISSIGRATE_V27|DISSIGRATE_V29)<<10,// 7 ?
  163. };
  164. u_int Class2Params::wdDISTab[8] = {
  165.     DISWIDTH_1728<<6,        // WD_1728
  166.     DISWIDTH_2048<<6,        // WD_2048
  167.     DISWIDTH_2432<<6,        // WD_2432
  168.     DISWIDTH_1728<<6,        // WD_1216 XXX
  169.     DISWIDTH_1728<<6,        // WD_864 XXX
  170.     DISWIDTH_1728<<6,        // 5
  171.     DISWIDTH_1728<<6,        // 6
  172.     DISWIDTH_1728<<6,        // 7
  173. };
  174. u_int Class2Params::lnDISTab[3] = {
  175.     DISLENGTH_A4<<4,        // LN_A4
  176.     DISLENGTH_A4B4<<4,        // LN_B4
  177.     DISLENGTH_UNLIMITED<<4    // LN_INF
  178. };
  179. u_int Class2Params::stDISTab[8] = {
  180.     DISMINSCAN_0MS<<1,        // ST_0MS
  181.     DISMINSCAN_5MS<<1,        // ST_5MS
  182.     DISMINSCAN_10MS2<<1,    // ST_10MS2
  183.     DISMINSCAN_10MS<<1,        // ST_10MS
  184.     DISMINSCAN_20MS2<<1,    // ST_20MS2
  185.     DISMINSCAN_20MS<<1,        // ST_20MS
  186.     DISMINSCAN_40MS2<<1,    // ST_40MS2
  187.     DISMINSCAN_40MS<<1,        // ST_40MS
  188. };
  189.  
  190. /*
  191.  * Convert a Class 2 bit rate code to a T.30
  192.  * DCS code.  Beware that certain entries map
  193.  * speeds and protocols (e.g. v.17 vs. v.33).
  194.  */
  195. u_int Class2Params::brDCSTab[8] = {
  196.     DCSSIGRATE_2400V27,        // BR_2400
  197.     DCSSIGRATE_4800V27,        // BR_4800
  198.     DCSSIGRATE_7200V29,        // BR_7200
  199.     DCSSIGRATE_9600V29,        // BR_9600
  200.     DCSSIGRATE_12000V17,    // BR_12000
  201.     DCSSIGRATE_14400V17,    // BR_14400
  202.     DCSSIGRATE_9600V29,        // 6 ?
  203.     DCSSIGRATE_9600V29,        // 7 ?
  204. };
  205. u_int Class2Params::stDCSTab[8] = {
  206.     DISMINSCAN_0MS<<1,        // ST_0MS
  207.     DISMINSCAN_5MS<<1,        // ST_5MS
  208.     DISMINSCAN_10MS<<1,        // ST_10MS2
  209.     DISMINSCAN_10MS<<1,        // ST_10MS
  210.     DISMINSCAN_20MS<<1,        // ST_20MS2
  211.     DISMINSCAN_20MS<<1,        // ST_20MS
  212.     DISMINSCAN_40MS<<1,        // ST_40MS2
  213.     DISMINSCAN_40MS<<1,        // ST_40MS
  214. };
  215.  
  216. /*
  217.  * Tables for mapping a T.30 DIS to Class 2
  218.  * subparameter code values.
  219.  */
  220. u_int Class2Params::DISdfTab[2] = {
  221.     DF_1DMR,            // !DIS_2DENCODE
  222.     DF_2DMR            // DIS_2DENCODE
  223. };
  224. u_int Class2Params::DISvrTab[2] = {
  225.     VR_NORMAL,            // !DIS_7MMVRES
  226.     VR_FINE            // DIS_7MMVRES
  227. };
  228. /*
  229.  * Beware that this table returns the ``best speed''
  230.  * based on the signalling capabilities of the DIS.
  231.  */
  232. u_int Class2Params::DISbrTab[16] = {
  233.     BR_4800,            // 0x0/V27FB
  234.     BR_14400,            // 0x1/V17
  235.     BR_9600,            // 0x2/undefined
  236.     BR_14400,            // 0x3/V17+undefined
  237.     BR_4800,            // 0x4/V27
  238.     BR_14400,            // 0x5/V17+V27
  239.     BR_4800,            // 0x6/V27+undefined
  240.     BR_14400,            // 0x7/V17+V27+undefined
  241.     BR_9600,            // 0x8/V29
  242.     BR_14400,            // 0x9/V17+V29
  243.     BR_9600,            // 0xA/V29+undefined
  244.     BR_14400,            // 0xB/V17+V29+undefined
  245.     BR_9600,            // 0xC/V29+V27
  246.     BR_14400,            // 0xD/V17+V29+V29
  247.     BR_9600,            // 0xE/V29+V27+undefined
  248.     BR_14400,            // 0xF/V17+V29+V29+undefined
  249. };
  250. u_int Class2Params::DISwdTab[4] = {
  251.     WD_1728,            // DISWIDTH_1728
  252.     WD_2432,            // DISWIDTH_2432
  253.     WD_2048,            // DISWIDTH_2048
  254.     WD_2432            // invalid, but treated as 2432
  255. };
  256. u_int Class2Params::DISlnTab[4] = {
  257.     LN_A4,            // DISLENGTH_A4
  258.     LN_INF,            // DISLENGTH_UNLIMITED
  259.     LN_B4,            // DISLENGTH_B4
  260.     LN_A4            // undefined
  261. };
  262. u_int Class2Params::DISstTab[8] = {
  263.     ST_20MS,            // DISMINSCAN_20MS
  264.     ST_40MS,            // DISMINSCAN_40MS
  265.     ST_10MS,            // DISMINSCAN_10MS
  266.     ST_10MS2,            // DISMINSCAN_10MS2
  267.     ST_5MS,            // DISMINSCAN_5MS
  268.     ST_40MS2,            // DISMINSCAN_40MS2
  269.     ST_20MS2,            // DISMINSCAN_20MS2
  270.     ST_0MS            // DISMINSCAN_0MS
  271. };
  272.  
  273. /*
  274.  * Convert a T.30 DIS to a Class 2 parameter block.
  275.  */
  276. void
  277. Class2Params::setFromDIS(u_int dis, u_int xinfo)
  278. {
  279.     vr = DISvrTab[(dis & DIS_7MMVRES) >> 9];
  280.     /*
  281.      * Beware that some modems (e.g. the Supra) indicate they
  282.      * support the V.17 bit rates, but not the normal V.27+V.29
  283.      * signalling rates.  The DISbrTab is NOT setup to mark the
  284.      * V.27 and V.29 if V.17 is set.  Instead we let the upper
  285.      * layers select appropriate signalling rate knowing that
  286.      * we'll fall back to something that the modem will support.
  287.      */
  288.     br = DISbrTab[(dis & DIS_SIGRATE) >> 10];
  289.     wd = DISwdTab[(dis & DIS_PAGEWIDTH) >> 6];
  290.     ln = DISlnTab[(dis & DIS_PAGELENGTH) >> 4];
  291.     if (xinfo & DIS_G4COMP)
  292.     df = DF_2DMMR;
  293.     else if (xinfo & DIS_2DUNCOMP)
  294.     df = DF_2DMRUNCOMP;
  295.     else
  296.     df = DISdfTab[(dis & DIS_2DENCODE) >> 8];
  297.     ec = (xinfo & DIS_ECMODE) ? EC_ENABLE : EC_DISABLE;
  298.     bf = BF_DISABLE;            // XXX from xinfo
  299.     st = DISstTab[(dis & DIS_MINSCAN) >> 1];
  300. }
  301.  
  302. u_int Class2Params::DCSbrTab[16] = {
  303.     BR_2400,            // 0x0/2400 V27
  304.     BR_14400,            // 0x1/14400 V17
  305.     BR_14400,            // 0x2/14400 V33
  306.     0,                // 0x3/undefined 
  307.     BR_4800,            // 0x4/4800 V27
  308.     BR_12000,            // 0x5/12000 V17
  309.     BR_12000,            // 0x6/12000 V33
  310.     0,                // 0x7/undefined 
  311.     BR_9600,            // 0x8/9600 V29
  312.     BR_9600,            // 0x9/9600 V17
  313.     BR_9600,            // 0xA/9600 V33
  314.     BR_7200,            // 0xB/7200 V17
  315.     BR_7200,            // 0xC/7200 V29
  316.     0,                // 0xD/undefined 
  317.     BR_7200,            // 0xE/7200 V33
  318.     0,                // 0xF/undefined 
  319. };
  320.  
  321. /*
  322.  * Convert a T.30 DCS to a Class 2 parameter block.
  323.  */
  324. void
  325. Class2Params::setFromDCS(u_int dcs, u_int xinfo)
  326. {
  327.     setFromDIS(dcs, xinfo);
  328.     br = DCSbrTab[(dcs & DCS_SIGRATE) >> 10];    // override DIS setup
  329. }
  330.  
  331. /*
  332.  * Return a T.30 DCS frame that reflects the parameters.
  333.  */
  334. u_int
  335. Class2Params::getDCS() const
  336. {
  337.     u_int dcs = DCS_T4RCVR
  338.         | vrDISTab[vr&1]
  339.         | brDCSTab[br&7]
  340.         | wdDISTab[wd&7]
  341.         | lnDISTab[ln&3]
  342.         | dfDISTab[df&3]
  343.         | stDCSTab[st&7]
  344.         ;
  345.     dcs = (dcs | DCS_XTNDFIELD) << 8;
  346.     /*
  347.      * NB: G4 is easy if we can negotiate it, but not a good
  348.      * idea unless the modem supports error correction.
  349.      */
  350.     if (df >= DF_2DMRUNCOMP)
  351.     dcs |= DCS_2DUNCOMP;
  352.     return (dcs);
  353. }
  354.  
  355. /*
  356.  * Return the number of bytes that can be
  357.  * transferred at the selected signalling
  358.  * rate in <ms> milliseconds.
  359.  */
  360. u_int
  361. Class2Params::transferSize(u_int ms) const
  362. {
  363.     static const u_int brRates[8] = {
  364.     2400/8,        // BR_2400
  365.     4800/8,        // BR_4800
  366.     7200/8,        // BR_7200
  367.     9600/8,        // BR_9600
  368.     12000/8,    // BR_12000
  369.     14400/8,    // BR_14400
  370.     14400/8,    // 6? XXX
  371.     14400/8,    // 7? XXX
  372.     };
  373.     return (brRates[br & 7] * ms) / 1000;
  374. }
  375.  
  376. /*
  377.  * Return the minimum number of bytes in a
  378.  * scanline as determined by the signalling
  379.  * rate, vertical resolution, and min-scanline
  380.  * time parameters.
  381.  */
  382. u_int
  383. Class2Params::minScanlineSize() const
  384. {
  385.     static const u_int stTimes[8] =
  386.     { 0, 5, 10, 10, 20, 20, 40, 40 };
  387.     u_int ms = stTimes[st&7];
  388.     if ((st & 1) == 0 && vr == VR_FINE)
  389.     ms /= 2;
  390.     return transferSize(ms);
  391. }
  392.